#include <Abracadabra/Presenter.hpp>

#include <string>
#include <optional>

#include <DotSort/GameRules/TubeSet.hpp>
#include <DotSort/TubeSetBuilder.hpp>

Presenter::Presenter(View::IView* view, TubeSetBuilder* builder)
	: view(view)
	, builder(builder)
	, tubeSet((*builder)())
{
	//this->tubeSet = (*this->builder)();
}

Presenter::~Presenter()
{
	delete this->tubeSet;
	delete this->builder;
}

void Presenter::onClick(std::optional<uint8_t> tubeIndex)
{
	if(tubeIndex)
	{
		if(this->selectedTube)
		{
			if(this->selectedTube == tubeIndex)
			{
				this->selectedTube = std::nullopt;
			}
			else if(this->tubeSet->isPossibleStep(*this->selectedTube, *tubeIndex))
			{
				this->tubeSet->doStep(*this->selectedTube, *tubeIndex);
				this->selectedTube = std::nullopt;
				this->view->update(*this->selectedTube, this->tubeSet->getTube(*this->selectedTube));
				this->view->update(*tubeIndex, this->tubeSet->getTube(*tubeIndex));
			}
		}
		else
		{
			this->selectedTube = tubeIndex;
		}
	}
	else
	{
		this->selectedTube = std::nullopt;
	}
}

void Presenter::onReload()
{
	delete this->tubeSet;
	this->selectedTube = std::nullopt;
	this->tubeSet = (*this->builder)();
	for(uint8_t i = 0; i < this->tubeSet->tubeCount; ++i)
	{
		this->view->update(i, this->tubeSet->getTube(i));
	}
}


void Presenter::onLevelChange(TubeSetBuilder* builder)
{
	delete this->tubeSet;
	this->selectedTube = std::nullopt;
	this->builder = builder;
	this->tubeSet = (*this->builder)();
	this->view->onNewLevel(this->tubeSet->tubeSize, this->tubeSet->tubeCount);
}

const std::vector<uint8_t>& Presenter::getDots(uint8_t tubeIndex) const
{
	return this->tubeSet->getTube(tubeIndex);
}
